/*
 * Javalin - https://javalin.io
 * Copyright 2017 David Åse
 * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
 */

package io.javalin

import com.mashape.unirest.http.Unirest
import io.javalin.core.util.Header
import io.javalin.util.TestUtil
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.isEmptyOrNullString
import org.junit.Test

class TestEtags {

    val etagsEnabledApp = Javalin.create().enableAutogeneratedEtags()

    @Test
    fun `default app does not set etags for GET`() = TestUtil.test { app, http ->
        app.get("/") { ctx -> ctx.result("Hello!") }
        assertThat(Unirest.get(http.origin + "/").asString().body, `is`("Hello!"))
        assertThat(Unirest.get(http.origin + "/").asString().status, `is`(200))
        assertThat(Unirest.get(http.origin + "/").asString().headers.getFirst(Header.ETAG), isEmptyOrNullString())
    }

    @Test
    fun `autogenerated etags are added to GET request`() = TestUtil.test(etagsEnabledApp) { app, http ->
        app.get("/automatic") { ctx -> ctx.result("Hello!") }
        val response = Unirest.get(http.origin + "/automatic").asString()
        assertThat(response.status, `is`(200))
        assertThat(response.body, `is`("Hello!"))
        val etag = response.headers.getFirst(Header.ETAG)
        val response2 = Unirest.get(http.origin + "/automatic").header(Header.IF_NONE_MATCH, etag).asString()
        val etag2 = response2.headers.getFirst(Header.ETAG)
        assertThat(response2.status, `is`(304))
        assertThat(response2.body, isEmptyOrNullString())
        assertThat(etag, `is`(etag2))
    }

    @Test
    fun `autogenerated etags are not added to PUT request`() = TestUtil.test(etagsEnabledApp) { app, http ->
        app.put("/automatic") { ctx -> ctx.result("Hello!") }
        val response = Unirest.put(http.origin + "/automatic").asString()
        assertThat(response.headers.getFirst(Header.ETAG), isEmptyOrNullString())
    }

    @Test
    fun `manual etags overwrite autogenerated etags`() = TestUtil.test(etagsEnabledApp) { app, http ->
        app.get("/manual") { ctx -> ctx.result("Hello!").header(Header.ETAG, "1234") }
        val response = Unirest.get(http.origin + "/manual").asString()
        assertThat(response.status, `is`(200))
        assertThat(response.body, `is`("Hello!"))
        val etag = response.headers.getFirst(Header.ETAG)
        val response2 = Unirest.get(http.origin + "/manual").header(Header.IF_NONE_MATCH, etag).asString()
        assertThat(response2.status, `is`(304))
        assertThat(response2.body, isEmptyOrNullString())
        assertThat(etag, `is`("1234"))
    }

    @Test
    fun `manual etags work for PUT request`() = TestUtil.test { app, http ->
        app.put("/manual") { ctx -> ctx.result("Hello!").header(Header.ETAG, "1234") }
        val response = Unirest.put(http.origin + "/manual").asString()
        assertThat(response.headers.getFirst(Header.ETAG), `is`("1234"))
    }

}
